
#include "KeyPair.h"
#include <openssl/rand.h>
#include "../iface/debug.h"

CRYPT_CONTEXT KeyPair::GetCryptContext_PublicKey(const char *name)
{
   errprint("This an abstract function.");
   return -1;
}

CRYPT_CONTEXT KeyPair::GetCryptContext_PrivateKey(const char *name)
{
   errprint("This an abstract function.");
   return -1;
}

CRYPT_CERTIFICATE KeyPair::GetCertificate_PublicKey(const char *name)
{
   int status;
   CRYPT_CERTIFICATE cert;
   CRYPT_CONTEXT cntxt = GetCryptContext_PublicKey(name);
   status = cryptCreateCert(&cert, CRYPT_UNUSED, CRYPT_CERTTYPE_CERTIFICATE);
   fCryptCheckError(status);
   status = cryptSetAttribute(cert, CRYPT_CERTINFO_XYZZY, 1);
   fCryptCheckError(status);
   status = cryptSetAttribute(cert, CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, cntxt);
   fCryptCheckError(status);
   status = cryptSetAttributeString(cert, CRYPT_CERTINFO_COMMONNAME, name, strlen(name));
   fCryptCheckError(status);
   status = cryptDestroyContext(cntxt);
   fCryptCheckError(status);
   return cert;
}

void KeyPair::SelfSignCert(CRYPT_CERTIFICATE cert, const char *name)
{
   int status;
   CRYPT_CONTEXT cntxt = GetCryptContext_PrivateKey(name);
   status = cryptSetAttribute(cert, CRYPT_CERTINFO_SELFSIGNED, 1);
   fCryptCheckError(status);
   status = cryptSignCert(cert, cntxt);
   fCryptCheckError(status);
   status = cryptDestroyContext(cntxt);
   fCryptCheckError(status);
}

char *KeyPair::ExportCertificateToText(CRYPT_CERTIFICATE cert)
{
   int status;
   int certsze = 0;
   status = cryptExportCert(NULL, 0, &certsze, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cert);
   fCryptCheckError(status);
   char *certificate_text = (char *)malloc(sizeof(char)*(certsze+1));
   status = cryptExportCert(certificate_text, certsze, &certsze, CRYPT_CERTFORMAT_TEXT_CERTIFICATE, cert);
   fCryptCheckError(status);
   certificate_text[certsze] = '\0';
   return certificate_text;
}

void KeyPair::GetEntropySource()
{
   int rsize = (RANDOMSIZE)/8;
   void *ranbuf = malloc(rsize);
   FILE *FP = fopen("/dev/urandom", "rb");
   if (!FP)
   {
      errprint("Couldn't open /dev/urandom.");
      return;
   }
   fread(ranbuf, rsize, 1, FP);
   fclose(FP);
   RAND_add(ranbuf, rsize, rsize);
   free(ranbuf);
}

char *KeyPair::ExportPrivateKey()
{
   errprint("This an abstract function.");
   return NULL;
}

char *KeyPair::ExportPasswordedPrivateKey(const char *password)
{
   errprint("This an abstract function.");
   return NULL;
}

int KeyPair::ImportPrivateKey(const char *encoded)
{
   errprint("This an abstract function.");
   return -1;
}

int KeyPair::ImportPasswordedPrivateKey(const char *password, const char *encoded)
{
   errprint("This an abstract function.");
   return -1;
}

char *KeyPair::ExportPublicKey()
{
   errprint("This an abstract function.");
   return NULL;
}

int KeyPair::ImportPublicKey(const char *encoded)
{
   errprint("This an abstract function.");
   return -1;
}

const char *KeyPair::GetKeyTypeName()
{
   errprint("This an abstract function.");
   return NULL;
}

char *KeyPair::GetMD5KeyFingerprint()
{
   errprint("This an abstract function.");
   return NULL;
}
